﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bibylon.BehafX.StateMachine.concept
{

    internal abstract class parallel : composite
    {
       

        /// <summary>
        /// @Copydoc - node::c'tor
        /// </summary>
        public parallel(string name, int nid, node parent)
            : base(name, nid, parent)
        {
            // Set no master, when just created.
           // Master = null;
        }

      
        /// <summary>
        /// master is node whose result have higher priority than others
        /// take for example, if master node succeeds, than whole parallel does
        /// </summary>
        // public node Master { get; set; }

      

        /// <summary>
        /// How to evaluate the execution result of the block
        /// </summary>
        /// 

        int strategy; // 0 = fail, 1 = pass
        int givenNumber; // Number of children to failed or passed to lead a success execution

        public void applyPolicy(int yesOrNo, int specifyNumber)
        {
            strategy = yesOrNo;
            givenNumber = specifyNumber; // specifyNumber < zero, means all of the children.
        }


        internal override int execute(object agent, object any)
        {
            int n = 0;
            int count = givenNumber < 0 ? Children.Count : givenNumber;

            Status result = Status.Failed;

            foreach ( node child in Children )
            {
                child.evaluate( agent, any );
                if (child.QueryStatus == Status.Failed && strategy == 0/*fail*/)
                    n++;
                else if (child.QueryStatus == Status.Successful && strategy == 1/*pass*/)
                    n++;

                if ( n >= count ) {// meets the specified number?
                    QueryStatus = Status.Successful;
                    return  (int)QueryStatus;
                }

                if (child.QueryStatus == Status.Running)
                    result = Status.Running;
            }

            return (int)result;
        }
            
    }
}
